import { _decorator, Color, find, instantiate, Node, Prefab, tween, Vec3 } from 'cc';
import ResManager from './ResManager';
import { LoadCtrl } from './LoadCtrl';
import { ShowTip } from './ShowTip';
import { PrefabEnum } from './PrefabEnum';
import { Modal } from './Modal';
import { EventManager } from '../event/EventManager';
import { TextTip } from '../fight/TextTip';
import { AudioManager, Mp3Enum } from './AudioManager';

const { ccclass, property } = _decorator;



@ccclass('UIManager')
export class UIManager {
    private static _instance;

    static get instance(): UIManager {
        if (this._instance == null) {
            this._instance = new UIManager();
        }
        return this._instance
    }

    private prefabMap: Map<string, Prefab> = new Map()
    private nodeMap: Map<string, Node> = new Map()

    /**打开UI */
    async openUI(prefabPath: string): Promise<Node> {
        
        AudioManager.instance.playOneShot(Mp3Enum.btn_confirm)
        

        await this.showLoading()

        if (this.nodeMap.has(prefabPath)) {
            this.closeLoading()
            return this.nodeMap.get(prefabPath)
        }

        let prefab
        if (this.prefabMap.has(prefabPath)) {
            prefab = this.prefabMap.get(prefabPath)
        } else {
            prefab = await ResManager.instance.loadAssetByUrl<Prefab>(prefabPath)
            this.prefabMap.set(prefabPath, prefab)
        }
        let node = instantiate(prefab)
        find('Canvas').addChild(node)
        this.nodeMap.set(prefabPath, node)


        tween(node)
            .to(0.1, { scale: new Vec3(1.1, 1.1, 1) }, { easing: 'elasticInOut' })
            .to(0.1, { scale: new Vec3(1, 1, 1) })
            .start()


        this.closeLoading()
        return node
    }

    /**关闭UI */
    closeUI(prefabPath: string,playSound:boolean = true) {
        if(playSound){
            AudioManager.instance.playOneShot(Mp3Enum.btn_confirm)
        }
        if (this.nodeMap.has(prefabPath)) {
            this.nodeMap.get(prefabPath).destroy()
            this.nodeMap.delete(prefabPath)
        }
    }

    
    /**UI是否打开 */
    isOpenUI(prefabPath: string): boolean {
        return this.nodeMap.has(prefabPath)
    }

    /**获取UI节点 */
    getUI(prefabPath: string):Node{
        return this.nodeMap.get(prefabPath)
    }

    /**加载场景 */
    async loadScene(sceneName: string) {
        this.clear()

        let prefab = await ResManager.instance.loadAssetByUrl<Prefab>(PrefabEnum.LoadScene)
        let node = instantiate(prefab)
        find('Canvas').addChild(node)
        node.getComponent(LoadCtrl).loadScene(sceneName)
    }

    /**
     * 关闭所有UI
     */
    clear() {
        for (let [key, value] of this.nodeMap) {
            this.closeUI(key)
        }
        this.nodeMap.clear()
    }

    /**消息提示 */
    async tip(str: string) {
        let prefab = await ResManager.instance.loadAssetByUrl<Prefab>(PrefabEnum.ShowTip)
        let node = instantiate(prefab)
        find('Canvas').addChild(node)
        node.getComponent(ShowTip).szMsg = str



    }

    /**模态框 */
    modal(title: string, content: string, isShowCancel: boolean = true): Promise<boolean> {
        return new Promise(async (resolve, reject) => {
            let node = await UIManager.instance.openUI(PrefabEnum.Modal)
            node.getComponent(Modal).show(title, content, isShowCancel)
            EventManager.instance.once(EventManager.EventType.ModalConfirm, (confirm) => {
                if (confirm) {
                    resolve(confirm)
                } else {
                    reject()
                }
            }, this)
        })
    }

    /**确认框 */
    confrim(obj:{title:string, content:string, isShowCancel?:boolean, cancelText?:string, confrimText?:string}): Promise<boolean> {
        return new Promise(async (resolve, reject) => {
            let node = await UIManager.instance.openUI(PrefabEnum.Modal)
            node.getComponent(Modal).showComfrim(obj)
            EventManager.instance.once(EventManager.EventType.ModalConfirm, (confirm) => {
                if (confirm) {
                    resolve(confirm)
                } else {
                    reject()
                }
            }, this)
        })
    }


    async showLoading() {




        let prefabPath = PrefabEnum.Loading
        if (this.nodeMap.has(prefabPath)) {

            return this.nodeMap.get(prefabPath)
        }

        let prefab
        if (this.prefabMap.has(prefabPath)) {
            prefab = this.prefabMap.get(prefabPath)
        } else {
            prefab = await ResManager.instance.loadAssetByUrl<Prefab>(prefabPath)
            this.prefabMap.set(prefabPath, prefab)
        }
        let node = instantiate(prefab)
        find('Canvas').addChild(node)
        this.nodeMap.set(prefabPath, node)


        setTimeout(() => {
            this.closeLoading()
        },3000)
    }

    async closeLoading() {
        console.log('closeLoading......')
        this.closeUI(PrefabEnum.Loading, false)
    }

    /**飘字 */
    async addTextTip(text: string, color: Color, pos: Vec3) {
        let profab = await ResManager.instance.loadAssetByUrl<Prefab>(PrefabEnum.TextTip)
        let tip = instantiate(profab)
        find('Canvas').addChild(tip)
        tip.getComponent(TextTip).setData(text, color, pos)
    }
}


